﻿using ApiLib.Helpers;
using ApiLib.Models;
using ApiLib.Utils;
using Furion;
using Furion.Schedule;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace ApiLib.AppStart;

/// <summary>
/// App配置
/// </summary>
public class AppCoreConfig
{
    /// <summary>
    /// 使用wwwroot，默认false
    /// </summary>
    public bool UseStaticFiles { get; init; } = false;

    /// <summary>
    /// 使用默认文件
    /// </summary>
    public bool UseDefaultFiles { get; init; } = false;

    /// <summary>
    /// 添加规范化结果状态码(401,403)，默认false
    /// </summary>
    public bool UseUnifyResultStatusCodes { get; init; } = false;

    /// <summary>
    /// 定时任务UI，默认false
    /// </summary>
    public bool UseScheduleUI { get; init; } = false;

    /// <summary>
    /// 定时任务监听，默认false
    /// </summary>
    public bool UseDefaultSchedule { get; init; } = false;

    /// <summary>
    /// http请求自动跳转到https，默认false
    /// </summary>
    public bool UseHttpsRedirection { get; init; } = false;

    /// <summary>
    /// 注册服务
    /// </summary>
    public Action<IServiceCollection>? ConfigureService { get; init; }

    /// <summary>
    /// 注册服务
    /// </summary>
    public Action<IApplicationBuilder, IWebHostEnvironment>? Configures { get; init; }

    /// <summary>
    /// 定时任务
    /// <example>
    /// <code>
    ///      ScheduleOptionsBuilder = builder =>
    ///      {
    ///          builder.AddJob&lt;MyOaJob>(TriggerBuilder.Cron("*/3 * * * *"));
    ///          builder.AddJob&lt;MyOaJob>(Triggers.PeriodMinutes(3).SetRunOnStart(true)); //启动时执行，每3分钟执行
    ///      }
    /// </code>
    /// </example>
    /// </summary>
    public Action<ScheduleOptionsBuilder>? ScheduleOptionsBuilder { get; init; }

    /// <summary>
    /// 文件上传目录，默认uploads
    /// </summary>
    public string UploadPath { get; init; } = "uploads";

    /// <summary>
    /// 认证
    /// </summary>
    public AbstractBaseAuthorization? BaseAuthorization { get; init; }

    /// <summary>
    /// 返回code值
    /// </summary>
    public BaseResponseCode? BaseResponseCode { get; init; }

    /// <summary>
    /// Banner类型
    /// <example><see href="https://www.bootschool.net/ascii-art">ascii-art</see></example>
    /// </summary>
    public BannerType BannerType { get; init; } = BannerType.Coder;

    /// <summary>
    /// 初始化默认配置
    /// </summary>
    public void InitAppConfig()
    {
        GlobalConfig.AppInfo = App.GetConfig<AppInfo>(nameof(AppInfo), true) ?? new AppInfo();
        GlobalConfig.AppConfig = App.GetConfig<AppConfig>(nameof(AppConfig), true);

        //初始化动态
        WebUtil.ScanComponents();
        //初始化用户配置
        InitMyAppConfig();
        //mongo初始化
        MongoUtil.Init();
        //redis初始化
        RedisCache.Init();

        //初始化依赖项目的配置方法
        var childInstances = AssemblyUtil.GetChildInstances<IBaseConfig>();
        foreach (var childInstance in childInstances)
        {
            if (childInstance is { ExecuteWeight: > 0 })
            {
                GlobalConfig.BaseConfigs.Add(childInstance);
            }
        }

        GlobalConfig.BaseConfigs.Sort((c1, c2) => c1.ExecuteWeight - c2.ExecuteWeight);
        foreach (var instance in GlobalConfig.BaseConfigs)
        {
            var methodInfo = instance.GetType().GetMethod(nameof(IBaseConfig.Config));
            methodInfo?.Invoke(instance, null);
        }
    }

    private void InitMyAppConfig()
    {
        //服务配置
        if (ConfigureService != null)
        {
            GlobalConfig.ConfigureServices.Add(ConfigureService);
        }

        //服务配置
        if (Configures != null)
        {
            GlobalConfig.Configures.Add(Configures);
        }

        if (ScheduleOptionsBuilder != null)
        {
            GlobalConfig.ScheduleOptionsBuilders.Add(ScheduleOptionsBuilder);
        }

        if (BaseResponseCode != null)
        {
            GlobalConfig.BaseResponseCode = BaseResponseCode;
        }

        GlobalConfig.BaseAuthorization = BaseAuthorization;
        GlobalConfig.UseStaticFiles = UseStaticFiles;
        GlobalConfig.UseDefaultFiles = UseDefaultFiles;
        GlobalConfig.UseUnifyResultStatusCodes = UseUnifyResultStatusCodes;
        GlobalConfig.UseScheduleUI = UseScheduleUI;
        GlobalConfig.UseDefaultSchedule = UseDefaultSchedule;
        GlobalConfig.UseHttpsRedirection = UseHttpsRedirection;
        GlobalConfig.UploadPath = UploadPath;
        GlobalConfig.BannerType = BannerType;

        /*//自定义的配置项
        var propertyInfos = this.GetType().GetProperties();
        var configFields = typeof(GlobalConfig).GetFields();
        foreach (var propertyInfo in propertyInfos)
        {
            switch (propertyInfo.Name)
            {
                case nameof(ConfigureService):
                    break;
                case nameof(Configures):
                    break;
                default:
                    var value = propertyInfo.GetValue(this);
                    if (value != null)
                    {
                        var config = configFields.FirstOrDefault(p => p.Name == propertyInfo.Name);
                        if (config != null && config.FieldType.IsSameTypeIgnoreNullable(propertyInfo.PropertyType))
                        {
                            config.SetValue(null, value);
                        }
                    }

                    break;
            }
        }*/
    }
}